home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d966.lha / UChessSrc / UChessSrc.lha / genmoves.c < prev    next >
C/C++ Source or Header  |  1994-01-29  |  11KB  |  415 lines

  1. /*
  2.  * genmoves.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. short __aligned *TrP;
  25.  
  26. #define Link(from,to,flag,s) \
  27. {\
  28.    node->f = from; node->t = to;\
  29.      node->reply = 0;\
  30.        node->flags = flag;\
  31.      node->score = s;\
  32.        ++node;\
  33.          (*TrP)++;\
  34.          }
  35.  
  36. #ifndef KILLT
  37. inline void
  38. LinkMove (ARGSZ int ply, ARGSZ int f,
  39.       ARGSZ int t,
  40.       ARGSZ int flag,
  41.       ARGSZ int xside)
  42. #else
  43. inline void
  44. LinkMove (ARGSZ int ply, ARGSZ int f,
  45.       ARGSZ int t,
  46.       ARGSZ int flag)
  47. #endif
  48.  
  49. /*
  50.  * Add a move to the tree.  Assign a bonus to order the moves as follows: 1.
  51.  * Principle variation 2. Capture of last moved piece 3. Other captures
  52.  * (major pieces first) 4. Killer moves 5.
  53.  */
  54.  
  55. {
  56.   register short s = 0;
  57. #if defined HISTORY
  58.   register short z;
  59. #endif
  60.   register unsigned short mv;
  61.   register struct leaf *node;
  62.  
  63.   node = &Tree[*TrP];
  64.   mv = (f << 8) | t;
  65. #ifdef KILLT
  66.   s += killt[mv | sidebit];
  67. #endif
  68. #ifdef HISTORY
  69.   z = mv;
  70.   if (xside == white) z |= 0x4000;
  71. /*TMPif (z > 32767) { printf("BAD BAD HIST IN GEN1\n");getchar(); }*/
  72.   s += history[z];
  73. #endif
  74.   if (color[t] != neutral)
  75.     {
  76.       /* TOsquare is the square the last piece moved moved to */
  77.       s +=  value[board[t]] - board[f] + ((t == TOsquare) ? 500 : 0);
  78.     }
  79.   if (board[f] == pawn)
  80.     if (row (t) == 0 || row (t) == 7)
  81.       {
  82.     flag |= promote;
  83.     s += 800;
  84. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  85.     Link (f, t, flag | queen, s - 20000);
  86.     s -= 200;
  87.     Link (f, t, flag | knight, s - 20000);
  88.     s -= 50;
  89.     Link (f, t, flag | rook, s - 20000);
  90.     flag |= bishop;
  91.     s -= 50;
  92. #else
  93.     flag |= queen;
  94. #endif
  95.       }
  96.     else if (row (t) == 1 || row (t) == 6)
  97.       {
  98.     flag |= pwnthrt;
  99.     s += 600;
  100.       }
  101.     else if ((row(t) == ((color[f] == white)?5:2)) && (ply > MINDEPTH) && (ply < Sdepth+3))
  102.       {
  103.     if ((mtl[white] - pmtl[white] + mtl[black] - pmtl[black]) < PTVALUE)
  104.       {
  105.         flag |= pwnthrt;
  106.         s += 400;
  107.       }
  108.       }
  109.   Link (f, t, flag, s - 20000);
  110. }
  111.  
  112. inline
  113. void
  114. GenMoves (ARGSZ int ply, ARGSZ int sq, ARGSZ int side, ARGSZ int xside)
  115.  
  116. /*
  117.  * Generate moves for a piece. The moves are taken from the precalulated
  118.  * array nextpos/nextdir. If the board is free, next move is choosen from
  119.  * nextpos else from nextdir.
  120.  */
  121.  
  122. {
  123.   register short u, piece;
  124.   register unsigned char *ppos, *pdir;
  125.  
  126.   TrP = &TrPnt[ply + 1];
  127.   piece = board[sq];
  128.   ppos = nextpos[ptype[side][piece]][sq];
  129.   pdir = nextdir[ptype[side][piece]][sq];
  130.   if (piece == pawn)
  131.     {
  132.       u = ppos[sq];        /* follow no captures thread */
  133.       if (color[u] == neutral)
  134.     {
  135. #ifndef KILLT
  136.       LinkMove (ply, sq, u, 0, xside);
  137. #else
  138.       LinkMove (ply, sq, u, 0);
  139. #endif
  140.       u = ppos[u];
  141.       if (color[u] == neutral)
  142. #ifndef KILLT
  143.         LinkMove (ply, sq, u, 0, xside);
  144. #else
  145.         LinkMove (ply, sq, u, 0);
  146. #endif
  147.     }
  148.       u = pdir[sq];        /* follow captures thread */
  149.       if (color[u] == xside && board[u] != king)
  150. #ifndef KILLT
  151.     LinkMove (ply, sq, u, capture, xside);
  152. #else
  153.     LinkMove (ply, sq, u, capture);
  154. #endif
  155.       u = pdir[u];
  156.       if (color[u] == xside && board[u] != king)
  157. #ifndef KILLT
  158.     LinkMove (ply, sq, u, capture, xside);
  159. #else
  160.     LinkMove (ply, sq, u, capture);
  161. #endif
  162.     }
  163.   else
  164.     {
  165.       u = ppos[sq];
  166.       do
  167.     {
  168.       if (color[u] == neutral)
  169.         {
  170. #ifndef KILLT
  171.           LinkMove (ply, sq, u, 0, xside);
  172. #else
  173.           LinkMove (ply, sq, u, 0);
  174. #endif
  175.           u = ppos[u];
  176.         }
  177.       else
  178.         {
  179.           if (color[u] == xside && board[u] != king)
  180. #ifndef KILLT
  181.         LinkMove (ply, sq, u, capture, xside);
  182. #else
  183.         LinkMove (ply, sq, u, capture);
  184. #endif
  185.           u = pdir[u];
  186.         }
  187.       } while (u != sq);
  188.     }
  189. }
  190.  
  191. void
  192. MoveList (INTSIZE int side, INTSIZE int ply)
  193.  
  194. /*
  195.  * Fill the array Tree[] with all available moves for side to play. Array
  196.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  197.  */
  198.  
  199. {
  200.   register short i, xside, f;
  201.  
  202.   xside = side ^ 1;
  203.   TrP = &TrPnt[ply + 1];
  204.   *TrP = TrPnt[ply];
  205.   if (!PV)
  206.     Swag0 = killr0[ply];
  207.    else Swag0 = PV;
  208.   Swag1 = killr1[ply];
  209.   Swag2 = killr2[ply];
  210.   Swag3 = killr3[ply];
  211.   if (ply > 2)
  212.     Swag4 = killr1[ply - 2]; else Swag4 = 0;
  213. #ifdef KILLT
  214.   sidebit = ((side == white) ? 0 : 0x80);
  215.   killt[SwagHt | sidebit] += 5000;
  216.   killt[Swag0 | sidebit] += 2000;
  217.   killt[Swag1 | sidebit] += 60;
  218.   killt[Swag2 | sidebit] += 50;
  219.   killt[Swag3 | sidebit] += 40;
  220.   killt[Swag4 | sidebit] += 30;
  221. #endif
  222. #ifdef HISTORY
  223.   i = (side == black)?0x4000:0;
  224. /*TMPif ((SwagHt | i) > 32767) { printf("BAD BAD HIST IN GEN2\n");getchar(); }*/
  225.   history[SwagHt | i] += 5000;
  226. /*TMPif ((Swag0 | i) > 32767) { printf("BAD BAD HIST IN GEN3\n");getchar(); }*/
  227.   history[Swag0 | i] += 2000;
  228. /*TMPif ((Swag1 | i) > 32767) { printf("BAD BAD HIST IN GEN4\n");getchar(); }*/
  229.   history[Swag1 | i] += 60;
  230. /*TMPif ((Swag2 | i) > 32767) { printf("BAD BAD HIST IN GEN5\n");getchar(); }*/
  231.   history[Swag2 | i] += 50;
  232. /*TMPif ((Swag3 | i) > 32767) { printf("BAD BAD HIST IN GEN6\n");getchar(); }*/
  233.   history[Swag3 | i] += 40;
  234. /*TMPif ((Swag4 | i) > 32767) { printf("BAD BAD HIST IN GEN7\n");getchar(); }*/
  235.   history[Swag4 | i] += 30;
  236. #endif
  237.   for (i = PieceCnt[side]; i >= 0; i--)
  238.     GenMoves (ply, PieceList[side][i], side, xside);
  239.   if (!castld[side])
  240.     {
  241.       f = PieceList[side][0];
  242.       if (castle (side, f, f + 2, 0))
  243.     {
  244. #ifndef KILLT
  245.       LinkMove (ply, f, f + 2, cstlmask, xside);
  246. #else
  247.       LinkMove (ply, f, f + 2, cstlmask);
  248. #endif
  249.     }
  250.       if (castle (side, f, f - 2, 0))
  251.     {
  252. #ifndef KILLT
  253.       LinkMove (ply, f, f - 2, cstlmask, xside);
  254. #else
  255.       LinkMove (ply, f, f - 2, cstlmask);
  256. #endif
  257.     }
  258.     }
  259.   if (epsquare > 0)
  260.     {
  261.       f = epmove1[epsquare];
  262.       if (color[f] == side && board[f] == pawn)
  263. #ifndef KILLT
  264.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  265. #else
  266.     LinkMove (ply, f, epsquare, capture | epmask);
  267. #endif
  268.       f = epmove2[epsquare];
  269.       if (color[f] == side && board[f] == pawn)
  270. #ifndef KILLT
  271.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  272. #else
  273.     LinkMove (ply, f, epsquare, capture | epmask);
  274. #endif
  275.     }
  276. #ifdef KILLT
  277.   killt[SwagHt | sidebit] -= 5000;
  278.   killt[Swag0 | sidebit] -= 2000;
  279.   killt[Swag1 | sidebit] -= 60;
  280.   killt[Swag2 | sidebit] -= 50;
  281.   killt[Swag3 | sidebit] -= 40;
  282.   killt[Swag4 | sidebit] -= 30;
  283. #endif
  284. #ifdef HISTORY
  285.  i = (side == black)?0x4000:0;
  286. /*TMPif ((SwagHt | i) > 32767) { printf("BAD BAD HIST IN GEN8\n");getchar(); }*/
  287.   history[SwagHt | i] -= 5000;
  288. /*TMPif ((Swag0 | i) > 32767) { printf("BAD BAD HIST IN GEN9\n");getchar(); }*/
  289.   history[Swag0 | i] -= 2000;
  290. /*TMPif ((Swag1 | i) > 32767) { printf("BAD BAD HIST IN GEN10\n");getchar(); }*/
  291.   history[Swag1 | i] -= 60;
  292. /*TMPif ((Swag2 | i) > 32767) { printf("BAD BAD HIST IN GEN11\n");getchar(); }*/
  293.   history[Swag2 | i] -= 50;
  294. /*TMPif ((Swag3 | i) > 32767) { printf("BAD BAD HIST IN GEN12\n");getchar(); }*/
  295.   history[Swag3 | i] -= 40;
  296. /*TMPif ((Swag4 | i) > 32767) { printf("BAD BAD HIST IN GEN13\n");getchar(); }*/
  297.   history[Swag4 | i] -= 30;
  298. #endif
  299.   SwagHt = 0;            /* SwagHt is only used once */
  300.   GenCnt += (TrPnt[ply+1] - TrPnt[ply]);
  301. }
  302.  
  303. void
  304. CaptureList (INTSIZE int side, INTSIZE int ply)
  305.  
  306. /*
  307.  * Fill the array Tree[] with all available cature and promote moves for side
  308.  * to play. Array TrPnt[ply] contains the index into Tree[] of the first move
  309.  * at a ply.
  310.  */
  311.  
  312. {
  313.   register short u, sq, xside;
  314.   register struct leaf *node;
  315.   register unsigned char *ppos, *pdir;
  316.   short i, piece, *PL, r7;
  317.  
  318.   xside = side ^ 1;
  319.   TrP = &TrPnt[ply + 1];
  320.   *TrP = TrPnt[ply];
  321.   node = &Tree[*TrP];
  322.   r7 = rank7[side];
  323.   PL = PieceList[side];
  324. #ifdef KILLT
  325.   sidebit = ((side == white) ? 0 : 0x80);
  326.   killt[SwagHt | sidebit] += 5000;
  327.   killt[Swag0 | sidebit] += 2000;
  328.   killt[Swag1 | sidebit] += 60;
  329.   killt[Swag2 | sidebit] += 50;
  330.   killt[Swag3 | sidebit] += 40;
  331.   killt[Swag4 | sidebit] += 30;
  332. #endif
  333.  
  334.   for (i = 0; i <= PieceCnt[side]; i++)
  335.     {
  336.       sq = PL[i];
  337.       piece = board[sq];
  338.       if (sweep[piece])
  339.     {
  340.       ppos = nextpos[piece][sq];
  341.       pdir = nextdir[piece][sq];
  342.       u = ppos[sq];
  343.       do
  344.         {
  345.           if (color[u] == neutral)
  346.         u = ppos[u];
  347.           else
  348.         {
  349.           if (color[u] == xside)
  350.             Link (sq, u, capture, value[board[u]] + svalue[board[u]] - piece);
  351.           u = pdir[u];
  352.         }
  353.       } while (u != sq);
  354.     }
  355.       else
  356.     {
  357.       pdir = nextdir[ptype[side][piece]][sq];
  358.       if (piece == pawn && row (sq) == r7)
  359.         {
  360.           u = pdir[sq];
  361.           if (color[u] == xside)
  362.                {
  363.         Link (sq, u, capture | promote | queen, valueQ);
  364. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  365.             Link (sq, u, capture | promote | knight, valueN);
  366.         Link (sq, u, capture | promote | rook, valueR);
  367.         Link (sq, u, capture | promote | bishop, valueB);
  368. #endif
  369.                }
  370.           u = pdir[u];
  371.           if (color[u] == xside)
  372.         {
  373.           Link (sq, u, capture | promote | queen, valueQ);
  374. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  375.           Link (sq, u, capture | promote | knight, valueN);
  376.           Link (sq, u, capture | promote | rook, valueR);
  377.           Link (sq, u, capture | promote | bishop, valueB);
  378. #endif
  379.         }
  380.           ppos = nextpos[ptype[side][piece]][sq];
  381.           u = ppos[sq];    /* also generate non capture promote */
  382.           if (color[u] == neutral)
  383.         {
  384.           Link (sq, u, promote | queen, valueQ);
  385. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  386.           Link (sq, u, promote | knight, valueN);
  387.           Link (sq, u, promote | rook, valueR);
  388.           Link (sq, u, promote | bishop, valueB);
  389. #endif
  390.         }
  391.         }
  392.       else
  393.         {
  394.           u = pdir[sq];
  395.           do
  396.         {
  397.           if (color[u] == xside)
  398.             Link (sq, u, capture, value[board[u]] + svalue[u] - piece);
  399.           u = pdir[u];
  400.           } while (u != sq);
  401.         }
  402.     }
  403.     }
  404. #ifdef KILLT
  405.   sidebit = ((side == white) ? 0 : 0x80);
  406.   killt[SwagHt | sidebit] -= 5000;
  407.   killt[Swag0 | sidebit] -= 2000;
  408.   killt[Swag1 | sidebit] -= 60;
  409.   killt[Swag2 | sidebit] -= 50;
  410.   killt[Swag3 | sidebit] -= 40;
  411.   killt[Swag4 | sidebit] -= 30;
  412. #endif
  413.   SwagHt = 0;            /* SwagHt is only used once */
  414. }
  415.